package mk.company.fin.frame;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
//import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;

import mk.company.fin.AppConstants;
import mk.company.fin.frame.internal.AbstractInternalFrame;
import mk.company.fin.frame.internal.ContoPlanFrame;
import mk.company.fin.frame.internal.FinansovNalogFrame;
import mk.company.fin.frame.internal.KomintentFrame;
import mk.company.fin.frame.internal.OrganizationSectorFrame;
import mk.company.fin.frame.internal.UserFrame;
import mk.company.fin.frame.report.internal.AnalyticCardReportFrame;
import mk.company.fin.frame.report.internal.FinalSheetReportFrame;
import mk.company.fin.frame.report.internal.KontoStatusReportFrame;
import mk.company.fin.frame.report.internal.ObligationPartnersReportFrame;
import mk.company.fin.frame.report.internal.OpenWarrantsEntryListReportFrame;
import mk.company.fin.frame.report.internal.SyntheticCardReportFrame;
import mk.company.fin.frame.report.internal.WarrantReportFrame;
import mk.company.fin.importer.KontoImporter;
//import mk.company.fin.main.GuiApplication;
import mk.company.fin.model.User;
import mk.company.fin.panel.CollapsiblePanel;
import mk.company.fin.service.IconService;
import mk.company.fin.service.LocaleService;
import mk.company.fin.service.MessageService;
import mk.company.fin.service.ModelService;
import mk.company.fin.thread.StartApplication;
import mk.company.fin.utils.AppUtils;
import mk.company.fin.utils.StringEntry;

import org.springframework.context.ApplicationContext;

/**
 * Main GUI frame window.
 * 
 * @author vlado.gjorgjiev
 */
public class FinFrame extends AbstractFrame {

	private static final long serialVersionUID = -218385230469914321L;
	
	/* SERVICES */
	
	private MessageService messageService;
	private LocaleService localeService;
	private IconService iconService;
	private KontoImporter kontoImporterService;
	private ModelService modelService;
	
	/* COMPONENTS: MENU */
	
	private JMenuBar menuBar;
	private JMenu appMenu;
	private JMenu langMenu;
//	private JMenu configMenu;
	private JMenuItem appBackMenuItem;
	private JMenuItem appLogoutMenuItem;
	private JMenuItem appExitMenuItem;
//	private JMenuItem configExportMenuItem;
//	private JMenuItem configImportMenuItem;
	private JRadioButtonMenuItem langMkMenuItem;
	private JRadioButtonMenuItem langEnMenuItem;
	
	/* COMPONENTS: RIGHT MENU */

	private JSplitPane splitPane;
	private JDesktopPane desktopPane;
	private JPanel rightMenu;
	
	/* COMPONENTS: RO HEADER */
	
	private JLabel header;
	
	
	/**
	 * Initialize the frame for the given context.
	 * @param context the context
	 */
	public void initialize(ApplicationContext context) {
		setContext(context);
		injectServices();
		// Defaults
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(new Dimension(AppConstants.MainFrame.WIDTH, AppConstants.MainFrame.HEIGHT));
		
		// components
		initComponents();
	}

	
	/**
	 * Inject services.
	 */
	private void injectServices() {
		messageService = getContext().getBean(MessageService.class);
		localeService = getContext().getBean(LocaleService.class);
		iconService = getContext().getBean(IconService.class);
		kontoImporterService= getContext().getBean(KontoImporter.class);
		modelService=getContext().getBean(ModelService.class);
	}

	/**
	 * Initialize the components.
	 */
	public void initComponents() {
		// title
		setTitle(messageService.getMessage("app.title"));
		setSize(300, 200);
		kontoImporterService.importFirstUser();
//		createMenuBar();
//		createPanes();
		splitPane=new JSplitPane();
		initLoginPanel();
		setContentPane(loginPanel);
		kontoImporterService.importKontos();
	}


	public void initComponents2() {
		// title
		setTitle(messageService.getMessage("app.title"));
		createMenuBar();
		createPanes();
		kontoImporterService.importKontos();
	}
	/**
	 * Create the menu bar.
	 */
	private void createMenuBar() {
		menuBar = new JMenuBar();
		appMenu = new JMenu();
		// 1. app back
		appBackMenuItem=new JMenuItem();
		appBackMenuItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				// go with thread
		        StartApplication startApp = new StartApplication(getFrame(),true);
		        Thread thread = new Thread(startApp);
		        thread.start();
			}
		});
		appMenu.add(appBackMenuItem);
		
		// 1. app logout
		appLogoutMenuItem = new JMenuItem();
		appMenu.add(appLogoutMenuItem);
		appLogoutMenuItem.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				loginPanel.removeAll();
				setContentPane(loginPanel);
				initLoginPanel();
			}
		});
		
		// 1. app exit
		appExitMenuItem = new JMenuItem();
		appExitMenuItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent actionevent) {
				System.exit(0);
			}
		});
		appMenu.add(appExitMenuItem);
		menuBar.add(appMenu);
		
		// 2. language mk
		langMenu = new JMenu();
		final Locale mkLocale = new Locale("mk");
		langMkMenuItem = new JRadioButtonMenuItem();
		langMkMenuItem.setSelected(localeService.isCurrentLocaleEqual(mkLocale));
		langMkMenuItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent actionevent) {
				if (langMkMenuItem.isSelected()) {
					localeService.setCurrentLocale(mkLocale);
					getContentPane().removeAll();
					
					// go with thread
			        StartApplication startApp = new StartApplication(getFrame(),true);
			        Thread thread = new Thread(startApp);
			        thread.start();
				}
			}
		});
		langMenu.add(langMkMenuItem);
		
		// 2. language en
		final Locale enLocale = new Locale("en");
		langEnMenuItem = new JRadioButtonMenuItem();
		langEnMenuItem.setSelected(localeService.isCurrentLocaleEqual(enLocale));
		langEnMenuItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent actionevent) {
				if (langEnMenuItem.isSelected()) {
					localeService.setCurrentLocale(enLocale);
					getContentPane().removeAll();					
					// go with thread
			        StartApplication startApp = new StartApplication(getFrame(),true);
			        Thread thread = new Thread(startApp);
			        thread.start();
				}
			}
		});
		langMenu.add(langEnMenuItem);
		menuBar.add(langMenu);
		
//		// 3. configuration export
//		configMenu = new JMenu();
//		configExportMenuItem = new JMenuItem();
//		configMenu.add(configExportMenuItem);
//		
//		// 3. configuration import
//		configImportMenuItem = new JMenuItem();
//		configMenu.add(configImportMenuItem);
//		menuBar.add(configMenu);
		
		// set menu bar
		
		setJMenuBar(menuBar);
		setMenuNames();
	}
	
	private void setMenuNames() {
		appMenu.setText(messageService.getMessage("menu.app"));
		appBackMenuItem.setText(messageService.getMessage("menu.app.back"));
		appLogoutMenuItem.setText(messageService.getMessage("menu.app.logout"));
		appExitMenuItem.setText(messageService.getMessage("menu.app.exit"));
		langMenu.setText(messageService.getMessage("menu.language"));
		langMkMenuItem.setText(messageService.getMessage("menu.language.mk"));
		langEnMenuItem.setText(messageService.getMessage("menu.language.en"));
//		configMenu.setText(messageService.getMessage("menu.configuration"));
//		configExportMenuItem.setText(messageService.getMessage("menu.configuration.exportdata"));
//		configImportMenuItem.setText(messageService.getMessage("menu.configuration.importdata"));
	}
	
	
	/**
	 * Creates the split and desktop panes.
	 */
	private void createPanes() {
		// left pane is desktop
		createLeftPane();
		
		// right pane is with box layout
		JPanel rightPane = createRightPane();

		// Collapsible panels icons
		Icon titleBgr = iconService.getIcon("rightmenu.collapsible.title");
		Icon titleBgrOver = iconService.getIcon("rightmenu.collapsible.title.over");
		Icon componentBgr = iconService.getIcon("rightmenu.collapsible.component");
		Icon componentBgrOver = iconService.getIcon("rightmenu.collapsible.component.over");

		// 1. Collapsible panel
		CollapsiblePanel cPanel = new CollapsiblePanel(rightMenu, titleBgr, titleBgrOver, componentBgr, componentBgrOver);
		createRightMenuInputData(cPanel);
		
		// 2. Collapsible panel
		cPanel = new CollapsiblePanel(rightMenu, titleBgr, titleBgrOver, componentBgr, componentBgrOver);
		createRightMenuReports(cPanel);
		
		// 3. Collapsible panel
		cPanel = new CollapsiblePanel(rightMenu, titleBgr, titleBgrOver, componentBgr, componentBgrOver);
		createRightMenuFinalizing(cPanel);
		
		// 4. Collapsible panel
		cPanel = new CollapsiblePanel(rightMenu, titleBgr, titleBgrOver, componentBgr, componentBgrOver);
		createRightMenuReferents(cPanel);
		
		// 5. Collapsible panel
		cPanel = new CollapsiblePanel(rightMenu, titleBgr, titleBgrOver, componentBgr, componentBgrOver);
		createRightMenuCodesBook(cPanel);
		
		// split pane as content pane
		splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, desktopPane, rightPane);
		setContentPane(splitPane);
	}

	
	private void createLeftPane() {
		desktopPane = new JDesktopPane();
		desktopPane.setBackground(AppConstants.Colors.GRAY);
		

//		JInternalFrame testInternal = new JInternalFrame("Äîáðåäî¼äîâòå", true, true, true);
//		testInternal.setSize(AppConstants.LeftFrame.WIDTH, AppConstants.LeftFrame.HEIGHT);
//		testInternal.setVisible(true);
//		desktopPane.add(testInternal);
	}
	
	private JPanel createRightPane() {
		// header
		header = new JLabel();
		header.setHorizontalAlignment(JLabel.LEFT);
		header.setVerticalAlignment(JLabel.CENTER);
		header.setHorizontalTextPosition(JLabel.RIGHT);
		header.setVerticalTextPosition(JLabel.CENTER);
		header.setBackground(AppConstants.Colors.LIGHT_GRAY);
		
		// TODO remove this
		header.setText(AppUtils.renderAsHtml("Јавно претпријатие \"Улици и патишта\"", true));
		header.setIcon(new ImageIcon(this.getClass().getResource("/files/logo.jpg")));
		
		// the main right panel
		JPanel mainRightMenu = new JPanel();
		mainRightMenu.setLayout(new BoxLayout(mainRightMenu, BoxLayout.Y_AXIS));
		mainRightMenu.add(header);
		
		// inner panel
		rightMenu = new JPanel();
		rightMenu.setLayout(new BoxLayout(rightMenu, BoxLayout.Y_AXIS));
		JScrollPane scrollPane = new JScrollPane(rightMenu, 
				JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 
				JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		rightMenu.setBackground(AppConstants.Colors.LIGHT_BLUE);
		
		mainRightMenu.add(scrollPane);
		return mainRightMenu;
	}
	
	
	private void createRightMenuInputData(CollapsiblePanel cPanel) {

		cPanel.setTitle(messageService.getMessage("rightmenu.inputdata.title"));
		cPanel.createComponent(messageService.getMessage("rightmenu.inputdata.nalog"),this,new FinansovNalogFrame(desktopPane));
		
	}
	
	private void createRightMenuReports(CollapsiblePanel cPanel) {
		cPanel.setTitle(messageService.getMessage("rightmenu.reports.title"));
		cPanel.createComponent(messageService.getMessage("rightmenu.reports.analytic.card"), this, new AnalyticCardReportFrame(desktopPane));
		cPanel.createComponent(messageService.getMessage("rightmenu.reports.final.sheet"), this, new FinalSheetReportFrame(desktopPane));
		cPanel.createComponent(messageService.getMessage("rightmenu.reports.obligations.per.partners"), this, new ObligationPartnersReportFrame(desktopPane));
		cPanel.createComponent(messageService.getMessage("rightmenu.reports.warrants.report"), this, new WarrantReportFrame(desktopPane));
		cPanel.createComponent(messageService.getMessage("rightmenu.reports.open.warrant.entries.list.report"), this, new OpenWarrantsEntryListReportFrame(desktopPane));
		cPanel.createComponent(messageService.getMessage("rightmenu.reports.conto.status.report"), this, new KontoStatusReportFrame(desktopPane));
		cPanel.createComponent(messageService.getMessage("rightmenu.reports.synthetic.card.report"), this, new SyntheticCardReportFrame(desktopPane));
	}

	private void createRightMenuFinalizing(CollapsiblePanel cPanel) {
		cPanel.setTitle(messageService.getMessage("rightmenu.finalizing.title"));
	}
	
	private void createRightMenuReferents(CollapsiblePanel cPanel) {
		cPanel.setTitle(messageService.getMessage("rightmenu.referents.title"));
		cPanel.createComponent(messageService.getMessage("rightmenu.referents.users"), this, new UserFrame(desktopPane));
//		cPanel.createComponent(messageService.getMessage("rightmenu.referents.changepassword"), null, null);
//		cPanel.createComponent(messageService.getMessage("rightmenu.referents.ro"), null, null);
	}
	
	private void createRightMenuCodesBook(CollapsiblePanel cPanel) {
		cPanel.setTitle(messageService.getMessage("rightmenu.codesbook.title"));
		cPanel.createComponent(messageService.getMessage("rightmenu.codesbook.kontoplan"), this, new ContoPlanFrame(desktopPane));
		cPanel.createComponent(messageService.getMessage("rightmenu.codesbook.komintents"), this, new KomintentFrame(desktopPane));
		cPanel.createComponent(messageService.getMessage("rightmenu.codesbook.mtr"), this, new OrganizationSectorFrame(desktopPane));
	}
	
	
	
	/* GETTER FOR SPECIAL NEEDS */
	
	public JSplitPane getSplitPane() {
		return this.splitPane;
	}
	
	public FinFrame getFrame() {
		return this;
	}
	
	
	/* Draw a Internal Frame depending on what the user had selected */
	public void drawInternalFrame(AbstractInternalFrame internalFrame){
		desktopPane.removeAll();
		internalFrame.draw();
		setContentPane(desktopPane);
	}

	private javax.swing.JButton loginButton;
	private javax.swing.JPanel loginPanel;
	private javax.swing.JPasswordField passwordField;
	private javax.swing.JLabel passwordLabel;
	private javax.swing.JTextField usernameField;
	private javax.swing.JLabel usernameLabel;
	
	private void initLoginPanel() {
		
		loginPanel = new javax.swing.JPanel();
		
		splitPane.setVisible(false);
		if (menuBar!=null)
			menuBar.setVisible(false);
		Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
		setSize(300, 150);
		int x = (dim.width-300)/2;
		int y = (dim.height-150)/2;
		setLocation(x, y);
        usernameLabel = new javax.swing.JLabel(messageService.getMessage("login.username"));
        usernameField = new javax.swing.JTextField();
        usernameField.setColumns(10);
        passwordLabel = new javax.swing.JLabel(messageService.getMessage("login.password"));
        passwordField = new javax.swing.JPasswordField();
        passwordField.setColumns(10);
        loginButton = new javax.swing.JButton();
        loginButton.setText(messageService.getMessage("login.login"));
        loginButton.addActionListener(new ActionListener() {
			
			@SuppressWarnings("deprecation")
			@Override
			public void actionPerformed(ActionEvent e) {
				List<StringEntry> properties = new ArrayList<StringEntry>(2);
				properties.add(new StringEntry("base.username", "'" + usernameField.getText() + "'"));
				List<User> userList=modelService.findByProperties(User.class, null, properties);
				if (userList.size()==0){
					JOptionPane.showMessageDialog(loginPanel, messageService.getMessage("login.form.fail"),"Error", JOptionPane.ERROR_MESSAGE);
					return;
				}
				User user=userList.get(0);
				if (passwordField.getText().equals(user.getPassword())){
					if (!user.isActive()) {
						JOptionPane.showMessageDialog(loginPanel, messageService.getMessage("login.form.not.active"),"Error", JOptionPane.ERROR_MESSAGE);
						return;
					}
					setSize(new Dimension(AppConstants.MainFrame.WIDTH, AppConstants.MainFrame.HEIGHT));
					Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
					int x = (dim.width-AppConstants.MainFrame.WIDTH)/2;
					int y = (dim.height-AppConstants.MainFrame.HEIGHT)/2;
					setLocation(x, y);
					createMenuBar();
					createPanes();
					setContentPane(splitPane);
				}
				else {
					JOptionPane.showMessageDialog(loginPanel, messageService.getMessage("login.form.fail"),"Error", JOptionPane.ERROR_MESSAGE);
					return;
				}
			}
		});
        setLoginPanelLayout();
	}
	
	private void setLoginPanelLayout(){
		javax.swing.GroupLayout loginPanelLayout = new javax.swing.GroupLayout(loginPanel);
        loginPanel.setLayout(loginPanelLayout);
        loginPanelLayout.setHorizontalGroup(
            loginPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(loginPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(loginPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(usernameLabel)
                    .addComponent(passwordLabel))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(loginPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(loginPanelLayout.createSequentialGroup()
                        .addComponent(loginButton)
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addGroup(loginPanelLayout.createSequentialGroup()
                        .addGroup(loginPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(usernameField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(passwordField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addContainerGap(25, Short.MAX_VALUE))))
        );
        loginPanelLayout.setVerticalGroup(
            loginPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(loginPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(loginPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(usernameLabel)
                    .addComponent(usernameField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(loginPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(passwordLabel)
                    .addComponent(passwordField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(loginButton)
                .addContainerGap(20, Short.MAX_VALUE))
        );
//
        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(loginPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(206, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(loginPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(183, Short.MAX_VALUE))
        );
	}
	
	
}
